home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / dmake / save / run.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-23  |  5.3 KB  |  283 lines

  1.  
  2. /*
  3.  *  RUN.C
  4.  */
  5.  
  6. #include "defs.h"
  7. #ifdef AMIGA
  8. #include <dos/dosextens.h>
  9. #include <dos/var.h>
  10. #else
  11. #include <sys/wait.h>
  12. #endif
  13.  
  14. typedef struct CommandLineInterface CLI;
  15. typedef struct Process            Process;
  16.  
  17. Prototype long Execute_Command(char *, short);
  18. Prototype void InitCommand(void);
  19. Prototype long LoadSegLock(long, char *);
  20.  
  21. #ifdef AMIGA
  22. BPTR SaveLock;
  23. #endif
  24. char RootPath[512];
  25.  
  26. extern struct Library *SysBase;
  27.  
  28. void
  29. ICExit()
  30. {
  31. #ifdef AMIGA
  32.     if (SaveLock) {
  33.     UnLock(CurrentDir(SaveLock));
  34.     SaveLock = NULL;
  35.     }
  36. #endif
  37. }
  38.  
  39. void
  40. InitCommand()
  41. {
  42. #ifdef AMIGA
  43.     SaveLock = CurrentDir(DupLock(((Process *)FindTask(NULL))->pr_CurrentDir));
  44. #endif
  45.     getcwd(RootPath, sizeof(RootPath));
  46.     atexit(ICExit);
  47. }
  48.  
  49. /*
  50.  *  cmd[-1] is valid space and, in fact, must be long word aligned!
  51.  */
  52.  
  53. long
  54. Execute_Command(char *cmd, short ignore)
  55. {
  56.     register char *ptr;
  57.  
  58.     for (ptr = cmd; *ptr && *ptr != ' ' && *ptr != '\t' && *ptr != '\n'; ++ptr)
  59.     ;
  60.  
  61.  
  62.     /*
  63.      *    Internal MakeDir because AmigaDOS 2.04's MakeDir is unreliable
  64.      *    with RunCommand() (it can crash)
  65.      *
  66.      *    Internal CD because we special case it
  67.      */
  68.  
  69. #ifdef AMIGA
  70.     if (ptr - cmd == 7 && strnicmp(cmd, "makedir", 7) == 0) {
  71.     long lock;
  72.     short err = 0;
  73.  
  74.     while (*ptr == ' ' || *ptr == '\t')
  75.         ++ptr;
  76.     if (lock = CreateDir(ptr))
  77.         UnLock(lock);
  78.     else {
  79.         printf("Unable to makedir %s\n", ptr);
  80.         err = 20;
  81.     }
  82.     return((ignore) ? 0 : err);
  83.     } else
  84.     if (ptr - cmd == 6 && strnicmp(cmd, "fwrite", 6) == 0) {
  85.     char *t;
  86.     BPTR fh;
  87.     short err = 0;
  88.  
  89.     while (*ptr == ' ' || *ptr == '\t')
  90.         ++ptr;
  91.     for (t = ptr; *t && *t != ' ' && *t != '\t'; t++);
  92.     if (*t) *t++ = '\0';
  93.     if (fh = Open(ptr, MODE_NEWFILE)) {
  94.         int len;
  95.         len = strlen(t);
  96.         for(ptr = t; *ptr; ptr++) if (*ptr == ' ') *ptr = '\n';
  97.         t[len] = '\n';
  98.         Write(fh, t, len+1);
  99.         t[len] = '\0';
  100.         Close(fh);
  101.         err = 0;
  102.     }
  103.     else
  104.     {
  105.         printf("Unable to write %s\n", ptr);
  106.         err = 20;
  107.     }
  108.        return((ignore) ? 0 : err);
  109.     } else
  110. #endif
  111.     if (ptr - cmd == 2 && strnicmp(cmd, "cd", 2) == 0) {
  112.     long lock;
  113.     short err = 0;
  114.  
  115.     while (*ptr == ' ' || *ptr == '\t')
  116.         ++ptr;
  117.     {
  118.         short len = strlen(ptr);    /*  XXX HACK HACK */
  119.         if (len && ptr[len-1] == '\n')
  120.         ptr[len-1] = 0;
  121.     }
  122. #ifdef AMIGA
  123.     if (*ptr == 0)
  124.         lock = DupLock(SaveLock);
  125.     else
  126.         lock = Lock(ptr, SHARED_LOCK);
  127.     if (lock)
  128.         UnLock(CurrentDir(lock));
  129.     else {
  130.         printf("Unable to cd %s\n", ptr);
  131.         err = 20;
  132.     }
  133. #else
  134.     if (*ptr == 0)
  135.         err = chdir(RootPath);
  136.     else
  137.         err = chdir(ptr);
  138.     if (err != 0) {
  139.         err = 20;
  140.         printf("Unable to cd %s\n", ptr);
  141.     }
  142. #endif
  143.     return((ignore) ? 0 : err);
  144.     }
  145.  
  146.     /*
  147.      * run command cmd
  148.      *
  149.      */
  150.  
  151. #ifdef AMIGA
  152.     {
  153.     short i;
  154.     short ci;
  155.     short c;
  156.     short err = 0;
  157.     short useSystem = 0;
  158.     Process *proc = FindTask(NULL);
  159.     char *cmdArgs;
  160.  
  161.     for (i = 0; cmd[i] && cmd[i] != ' ' && cmd[i] != 9 && cmd[i] != 10 && cmd[i] != 13; ++i)
  162.         ;
  163.     if (strpbrk(cmd + i, "<>|`"))
  164.         useSystem = 1;
  165.     else
  166.         useSystem = 0;
  167.  
  168.     if (c = cmd[ci = i])
  169.         ++ci;
  170.     cmd[i] = 0;
  171.  
  172.     cmdArgs = malloc(strlen(cmd + ci) + 3);
  173.     sprintf(cmdArgs, "%s\n\r", cmd + ci);
  174.     fflush(stdout);
  175.  
  176.     /*
  177.      *  NOTE: RunCommand() is unreliable if no pr_CLI exists,
  178.      *  MUST use system13() in that case.
  179.      */
  180.  
  181. #if INCLUDE_VERSION >= 36
  182.     if (SysBase->lib_Version >= 36 && proc->pr_CLI) {
  183.         long seg;
  184.         long stack;
  185.         long lock = 0;
  186.         CLI *cli = (CLI *)BADDR(proc->pr_CLI);
  187.         static char OldCmd[128];
  188.         char dt[4];
  189.  
  190.         if (cli) {
  191.         GetProgramName(OldCmd, sizeof(OldCmd));
  192.         SetProgramName(cmd);
  193.         stack = cli->cli_DefaultStack * 4;
  194.         } else {
  195.         stack = 8192;
  196.         }
  197.  
  198.         /*
  199.          *    note: Running2_04() means V37 or greater
  200.          */
  201.  
  202.         if (useSystem || (Running2_04() && GetVar(cmd, dt, 2, LV_ALIAS | GVF_LOCAL_ONLY) >= 0))
  203.         goto dosys;
  204.  
  205.         if ((seg = FindSegment(cmd, 0L, 0)) || (seg = FindSegment(cmd, 0L, 1))) {
  206.         dbprintf(("A cmd = '%s' stack = %d\n", cmdArgs, stack));
  207.         err = RunCommand(((long *)seg)[2], stack, cmdArgs, strlen(cmdArgs) - 1);
  208.         } else if ((lock = _SearchPath(cmd)) && (seg = LoadSegLock(lock, ""))) {
  209.         dbprintf(("B\n"));
  210.         err = RunCommand(seg, stack, cmdArgs, strlen(cmdArgs) - 1);
  211.         UnLoadSeg(seg);
  212.         } else if ((lock = Lock("dcc:bin", SHARED_LOCK)) && (seg = LoadSegLock(lock, cmd))) {
  213.         dbprintf(("C %08x\n", seg));
  214.         dbprintf(("CMD= %s", cmdArgs));
  215.         err = RunCommand(seg, 8192, cmdArgs, strlen(cmdArgs) - 1);
  216.         UnLoadSeg(seg);
  217.         } else {
  218. dosys:
  219.         dbprintf(("D\n"));
  220.         cmd[i] = c;
  221.         /*err = system13(cmd);*/
  222.         err = System(cmd, NULL);
  223.         }
  224.         if (cli)
  225.         SetProgramName(OldCmd);
  226.         if (lock)
  227.         UnLock(lock);
  228.     } else
  229. #endif
  230.     {
  231.         dbprintf(("E\n"));
  232.         cmd[i] = c;
  233.         err = system13(cmd);
  234.     }
  235.     free(cmdArgs);
  236.     if (err)
  237.         printf("Exit code %d %s\n", err, (ignore) ? "(Ignored)":"");
  238.     if (ignore)
  239.         return(0);
  240.     return(err);
  241.     }
  242. #else
  243.     {
  244.     int err;
  245.  
  246.     if ((err = vfork()) == 0) {
  247.         execlp("/bin/sh", "/bin/sh", "-c", cmd, 0);
  248.         exit(30);
  249.     } else {
  250.         union wait uwait;
  251.  
  252.         while (wait(&uwait) != err || WIFEXITED(uwait) == 0)
  253.         ;
  254.         err = uwait.w_retcode;
  255.     }
  256.     if (err)
  257.         printf("Exit code %d %s\n", err, (ignore) ? "(Ignored)":"");
  258.     if (ignore)
  259.         return(0);
  260.     return(err);
  261.     }
  262. #endif
  263. }
  264.  
  265. #ifdef AMIGA
  266.  
  267. long
  268. LoadSegLock(lock, cmd)
  269. long lock;
  270. char *cmd;
  271. {
  272.     long oldLock;
  273.     long seg;
  274.  
  275.     oldLock = CurrentDir(lock);
  276.     seg = LoadSeg(cmd);
  277.     CurrentDir(oldLock);
  278.     return(seg);
  279. }
  280.  
  281.  
  282. #endif
  283.